package com.csu.letaobackend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.csu.letaobackend.bean.*;
import com.csu.letaobackend.commom.CommonResponse;
import com.csu.letaobackend.commom.SortBySales;
import com.csu.letaobackend.dto.Attr;
import com.csu.letaobackend.dto.ItemVO2;
import com.csu.letaobackend.persistence.*;
import com.csu.letaobackend.service.CatalogService;
import com.csu.letaobackend.vo.*;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Service
@MapperScan("com.csu.letaobackend.persistence")
public class CatalogServiceImpl implements CatalogService {

      @Autowired
      CategoryDao categoryDao;

      @Autowired
      ProductDao productDao;

      @Autowired
      ItemDao itemDao;

      @Autowired
      PictureDao pictureDao;

      @Autowired
      ItemattrDao itemattrDao;

      @Autowired
      ItemevalDao itemevalDao;

      @Autowired
      AttributesDao attributesDao;

      @Autowired
      AttrvaluesDao attrvaluesDao;

      @Autowired
      SpecialofferDao specialofferDao;

      @Autowired
      FavoriteitemDao favoriteitemDao;

      @Autowired
      ShopDao shopDao;

      @Autowired
      SwiperitemDao swiperitemDao;

      @Autowired
      BrowsingrecordDao browsingrecordDao;

      @Autowired
      OrderItemDao orderItemDao;

      @Override
      public CommonResponse<List<SwiperitemVO>> getSwiperitems() {
            List<Swiperitem> swiperitemList = swiperitemDao.selectList(null);
            List<SwiperitemVO> swiperitemVOList = new ArrayList<>();
            for (Swiperitem swiperitem : swiperitemList) {
                  swiperitemVOList.add(entityToVO(swiperitem));
            }
            return CommonResponse.createForSuccess(swiperitemVOList);
      }

      @Override
      public CommonResponse<List<CategoryVO>> getCategories() {
            List<Category> categoryList = categoryDao.selectList(null);
            List<CategoryVO> categoryVOList = new ArrayList<>();
            ;
            for (Category category : categoryList) {
                  categoryVOList.add(entityToVO(category));
            }
            return CommonResponse.createForSuccess(categoryVOList);
      }

      @Override
      public CommonResponse<List<ProductVO>> getProductsByCategoryId(int categoryId) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("categoryId", categoryId);
            List<Product> productList = productDao.selectList(queryWrapper);
            List<ProductVO> productVOList = new ArrayList<>();
            for (Product product : productList) {
                  productVOList.add(entityToVO(product));
            }
            return CommonResponse.createForSuccess(productVOList);
      }

      @Override
      public CommonResponse<List<ItemVO>> getItemsByProductId(int productId, String username) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("productId", productId);
            queryWrapper.eq("available", "1");
            List<Item> itemList = itemDao.selectList(queryWrapper);
            List<ItemVO> itemVOList = new ArrayList<>();
            for (Item item : itemList) {
                  itemVOList.add(entityToVO(item, username));
            }
            return CommonResponse.createForSuccess(itemVOList);
      }

      @Override
      public CommonResponse<List<ItemVO>> getItemsByProductId(int productId, int sortby, String username) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("productId", productId);
            queryWrapper.eq("available", "1");
            queryWrapper = sortWrapper(queryWrapper, sortby);

            List<Item> itemList = itemDao.selectList(queryWrapper);
            List<ItemVO> itemVOList = new ArrayList<>();
            for (Item item : itemList) {
                  itemVOList.add(entityToVO(item, username));
            }
            return CommonResponse.createForSuccess(itemVOList);
      }

      @Override
      public CommonResponse<IPage<ItemVO>> getItemsPages(int productId, int sortby, int currentPage, int pageSize, String username) {
            IPage<Item> itemPage = new Page<>(currentPage, pageSize);
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("productId", productId);
            queryWrapper.eq("available", "1");
            queryWrapper = sortWrapper(queryWrapper, sortby);
            itemDao.selectPage(itemPage, queryWrapper);

            List<ItemVO> itemVOList = new ArrayList<>();
            for (Item item : itemPage.getRecords()) {
                  itemVOList.add(entityToVO(item, username));
            }

            IPage<ItemVO> itemVOPage = new Page<>(currentPage, pageSize);
            itemVOPage.setTotal(itemPage.getTotal());
            itemVOPage.setRecords(itemVOList);

            return CommonResponse.createForSuccess(itemVOPage);
      }

      @Override
      public CommonResponse<ItemVO> getItem(int itemId, String username) {
            Item item = itemDao.selectById(itemId);

            return CommonResponse.createForSuccess(entityToVO(item, username));
      }

      @Override
      public CommonResponse<List<ItemAttrVO>> getAttrByItemId(int itemId) {
            List<ItemAttrVO> itemAttrVOList = new ArrayList<>();

            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("itemId", itemId);
            queryWrapper.orderByAsc("attrId");
            List<Itemattr> itemattrList = itemattrDao.selectList(queryWrapper);

            List<Itemattr> temp = new ArrayList<>();
            int flag = 0;
            for (int i = 0; i < itemattrList.size(); ) {
                  while (i < itemattrList.size() && flag == itemattrList.get(i).getAttrid()) {
                        temp.add(itemattrList.get(i));
                        i++;
                  }
                  if (temp.size() != 0)
                        itemAttrVOList.add(entityToVO(temp));
                  temp.clear();
                  if (i < itemattrList.size())
                        flag = itemattrList.get(i).getAttrid();
            }
            return CommonResponse.createForSuccess(itemAttrVOList);
      }

      @Override
      public CommonResponse<List<ItemVO>> getItemsByShopId(int shopId, int sortby, String username) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("shopId", shopId);
            queryWrapper = sortWrapper(queryWrapper, sortby);

            List<Item> itemList = itemDao.selectList(queryWrapper);
            List<ItemVO> itemVOList = new ArrayList<>();
            for (Item item : itemList) {
                  itemVOList.add(entityToVO(item, username));
            }
            return CommonResponse.createForSuccess(itemVOList);
      }

      @Override
      public CommonResponse<IPage<ItemVO>> getItemsPagesByShopId(int shopId, int sortby, int currentPage, int pageSize, String username) {
            IPage<Item> itemPage = new Page<>(currentPage, pageSize);
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("shopId", shopId);
            queryWrapper = sortWrapper(queryWrapper, sortby);
            itemDao.selectPage(itemPage, queryWrapper);

            List<ItemVO> itemVOList = new ArrayList<>();
            for (Item item : itemPage.getRecords()) {
                  itemVOList.add(entityToVO(item, username));
            }
            IPage<ItemVO> itemVOPage = new Page<>(currentPage, pageSize);
            itemVOPage.setTotal(itemPage.getTotal());
            itemVOPage.setRecords(itemVOList);

            return CommonResponse.createForSuccess(itemVOPage);
      }

      @Override
      public CommonResponse<IPage<ItemVO>> searchItemsPages(String keyword, int categoryId, int sortby, int currentPage, int pageSize, String username) {
            IPage<Item> itemPage = new Page<>(currentPage, pageSize);
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.like("description", keyword);
            if (categoryId != 0) {
                  QueryWrapper queryWrapper1 = new QueryWrapper();
                  queryWrapper1.eq("categoryId", categoryId);
                  List<Product> productList = productDao.selectList(queryWrapper1);
                  List<Integer> list = new ArrayList<>();
                  for (Product product : productList) {
                        list.add(product.getId());
                  }
                  queryWrapper.in("productId", list);
            }
            queryWrapper = sortWrapper(queryWrapper, sortby);
            itemDao.selectPage(itemPage, queryWrapper);

            List<ItemVO> itemVOList = new ArrayList<>();
            for (Item item : itemPage.getRecords()) {
                  itemVOList.add(entityToVO(item, username));
            }
            IPage<ItemVO> itemVOPage = new Page<>(currentPage, pageSize);
            itemVOPage.setTotal(itemPage.getTotal());
            itemVOPage.setRecords(itemVOList);

            return CommonResponse.createForSuccess(itemVOPage);
      }

      @Override
      public CommonResponse<List<ItemVO>> getPopularItems(int num) {
            List<ItemVO> itemVOList = new ArrayList<>();
            for (Item item : itemDao.selectList(null)) {
                  itemVOList.add(entityToVO(item, null));
            }

            Collections.sort(itemVOList, new SortBySales());
            Collections.reverse(itemVOList);
            if (itemVOList.size() > num) {
                  return CommonResponse.createForSuccess(itemVOList.subList(0, num));
            } else {
                  return CommonResponse.createForSuccess(itemVOList);
            }

      }

      @Override
      public CommonResponse<ItemVO> updateStockByItemId(int itemId, int stock) {
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.eq("id", itemId);
            updateWrapper.set("stock", stock);
            itemDao.update(null, updateWrapper);
            Item item = itemDao.selectById(itemId);
            return CommonResponse.createForSuccess("更新库存成功", entityToVO(item, null));
      }

      @Override
      public CommonResponse<ItemVO> updatePriceByItemId(int itemId, double price) {
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.eq("id", itemId);
            updateWrapper.set("price", price);
            itemDao.update(null, updateWrapper);
            Item item = itemDao.selectById(itemId);
            return CommonResponse.createForSuccess("更新价格成功", entityToVO(item, null));
      }

      @Override
      public CommonResponse updateByItemId(int itemId, int stock, double price, String description) {
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.eq("id", itemId);
            updateWrapper.set("stock", stock);
            updateWrapper.set("price", price);
            updateWrapper.set("description", description);
            itemDao.update(null, updateWrapper);
            return CommonResponse.createForSuccess("修改成功");
      }

      @Override
      public CommonResponse updateAvailableByItemId(int itemId, int available) {
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.eq("id", itemId);
            updateWrapper.set("available", available);
            itemDao.update(null, updateWrapper);
            return CommonResponse.createForSuccess("修改成功");
      }

      @Override
      public CommonResponse<Specialoffer> updateSpecialRateByItemId(int itemId, double specialRate) {
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.eq("itemid", itemId);
            updateWrapper.set("rate", specialRate);
            specialofferDao.update(null, updateWrapper);

            return CommonResponse.createForSuccess("更新优惠率成功", specialofferDao.selectById(itemId));
      }

      @Override
      public CommonResponse additem(ItemVO2 itemVO2) {
            Item item = VOtoEntity(itemVO2);
            itemDao.insert(item);
            if (itemVO2.getItemattrlist() != null) {
                  for (Attr attr : itemVO2.getItemattrlist()) {
                        for (int valueid : attr.getAttrvalsid()) {
                              Itemattr itemattr = new Itemattr();
                              itemattr.setItemid(item.getId());
                              itemattr.setAttrid(attr.getAttrid());
                              itemattr.setValueid(valueid);
                              itemattr.setRate(1);
                              itemattr.setPictureid(1);
                              itemattrDao.insert(itemattr);
                        }
                  }
            }
            return CommonResponse.createForSuccess("新增商品成功");
      }

      @Override
      public CommonResponse updateitem(int itemid, int stock, int price, String description) {
            Item item = itemDao.selectById(itemid);
            item.setStock(stock);
            item.setPrice(price);
            item.setDescription(description);
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.eq("id", item.getId());
            itemDao.update(item, updateWrapper);
            return CommonResponse.createForSuccessMessage("更新成功");
      }

      private Item VOtoEntity(ItemVO2 itemVO2) {
            Item item = new Item();
            item.setId(getMaxItemId() + 1);
            item.setProductid(itemVO2.getProductid());
            item.setShopid(itemVO2.getShopid());
            item.setPrice(itemVO2.getPrice());
            item.setStock(itemVO2.getStock());
            item.setPictureid(itemVO2.getPictureid());
            item.setDescription(itemVO2.getDescription());
            item.setVideoid(0);
            item.setAvailable(itemVO2.getAvailable());
            item.setIsnew(itemVO2.getIsnew());
            item.setIsrecommend(itemVO2.getIsrecommend());
            return item;
      }

      private int getMaxItemId() {
            List<Integer> list = new ArrayList<>();
            for (Item item : itemDao.selectList(null)) {
                  list.add(item.getId());
            }
            if (list.size() == 0)
                  return 0;
            return Collections.max(list);
      }

      @Override
      public CommonResponse<List<BrowsingrecordVO>> getRecords(String username) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("username", username);
            List<Browsingrecord> browsingrecordList = browsingrecordDao.selectList(queryWrapper);
            List<BrowsingrecordVO> browsingrecordVOList = new ArrayList<>();

            for (Browsingrecord browsingrecord : browsingrecordList) {
                  browsingrecordVOList.add(entityToVO(browsingrecord));
            }
            return CommonResponse.createForSuccess(browsingrecordVOList);
      }

      @Override
      public CommonResponse<BrowsingrecordVO> insertRecord(int itemid, String username) {
            Browsingrecord browsingrecord = new Browsingrecord();
            browsingrecord.setItemid(itemid);
            browsingrecord.setUsername(username);
            browsingrecord.setTime(new Date());
            browsingrecordDao.insert(browsingrecord);
            return CommonResponse.createForSuccess("插入浏览记录成功", entityToVO(browsingrecord));
      }

      private QueryWrapper sortWrapper(QueryWrapper queryWrapper, int sortby) {
            switch (sortby) {
                  case 0:
                        queryWrapper.orderByAsc("id");
                        break;
                  case 1:
                        queryWrapper.orderByAsc("description");
                        break;
                  case 2:
                        queryWrapper.orderByDesc("description");
                        break;
                  case 3:
                        queryWrapper.orderByAsc("price");
                        break;
                  case 4:
                        queryWrapper.orderByDesc("price");
                        break;
                  case 5:
                        queryWrapper.orderByAsc("stock");
                        break;
                  case 6:
                        queryWrapper.orderByDesc("stock");
                        break;
            }
            return queryWrapper;
      }

      private SwiperitemVO entityToVO(Swiperitem swiperitem) {
            Picture picture = pictureDao.selectById(swiperitem.getPictureid());
            SwiperitemVO swiperitemVO = new SwiperitemVO();
            swiperitemVO.setItemid(swiperitem.getItemid());
            swiperitemVO.setPictureid(swiperitem.getPictureid());
            swiperitemVO.setSrc(picture.getSrc());
            swiperitemVO.setDescription(swiperitem.getDescription());
            swiperitemVO.setSlogan(swiperitem.getSlogan());
            swiperitemVO.setStarttime(swiperitem.getStarttime());
            swiperitemVO.setEndtime(swiperitem.getEndtime());
            swiperitemVO.setAvailable(swiperitem.getAvailable());
            swiperitemVO.setClick(swiperitem.getAvailable());
            Item item = itemDao.selectById(swiperitem.getItemid());
            swiperitemVO.setShopname(shopDao.selectById(item.getShopid()).getName());
            return swiperitemVO;
      }

      private BrowsingrecordVO entityToVO(Browsingrecord browsingrecord) {
            Item item = itemDao.selectById(browsingrecord.getItemid());
            BrowsingrecordVO browsingrecordVO = new BrowsingrecordVO();
            browsingrecordVO.setUsername(browsingrecord.getUsername());
            browsingrecordVO.setTime(browsingrecord.getTime());
            browsingrecordVO.setItemid(browsingrecord.getItemid());
            browsingrecordVO.setPrice(item.getPrice());
            browsingrecordVO.setDescription(item.getDescription());
            browsingrecordVO.setStar(getAvgStar(item));
            browsingrecordVO.setStock(item.getStock());
            int pictureid = itemDao.selectById(browsingrecord.getItemid()).getPictureid();
            browsingrecordVO.setSrc(pictureDao.selectById(pictureid).getSrc());
            browsingrecordVO.setShopid(itemDao.selectById(browsingrecord.getItemid()).getShopid());
            browsingrecordVO.setShopname(shopDao.selectById(browsingrecordVO.getShopid()).getName());
            return browsingrecordVO;
      }

      private CategoryVO entityToVO(Category category) {
            Picture picture = pictureDao.selectById(category.getPictureid());
            CategoryVO categoryVO = new CategoryVO();
            categoryVO.setId(category.getId());
            categoryVO.setName(category.getName());
            categoryVO.setPictureid(category.getPictureid());
            categoryVO.setSrc(picture.getSrc());
            return categoryVO;
      }

      private ProductVO entityToVO(Product product) {
            Picture picture = pictureDao.selectById(product.getPictureid());
            ProductVO productVO = new ProductVO();
            productVO.setId(product.getId());
            productVO.setName(product.getName());
            productVO.setCategoryid(product.getCategoryid());
            productVO.setPictureid(product.getPictureid());
            productVO.setSrc(picture.getSrc());
            return productVO;
      }

      private ItemVO entityToVO(Item item, String username) {
            Picture picture = pictureDao.selectById(item.getPictureid());
            double star = getAvgStar(item);
            ItemVO itemVO = new ItemVO();
            itemVO.setId(item.getId());
            itemVO.setProductid(item.getProductid());
            itemVO.setShopid(item.getShopid());
            itemVO.setShopname(shopDao.selectById(item.getShopid()).getName());
            itemVO.setPrice(item.getPrice());
            itemVO.setStock(item.getStock());
            itemVO.setPictureid(item.getPictureid());
            itemVO.setDescription(item.getDescription());
            itemVO.setVideoid(item.getVideoid());
            itemVO.setAvailable(item.getAvailable());
            itemVO.setIsnew(item.getIsnew());
            itemVO.setIsrecommend(item.getIsrecommend());

            if (picture != null) {
                  itemVO.setSrc(picture.getSrc());
            }
            itemVO.setStar(String.valueOf(star));
            if (username == null)
                  itemVO.setIsFavorite(0);
            else {
                  QueryWrapper queryWrapper = new QueryWrapper();
                  queryWrapper.eq("username", username);
                  queryWrapper.eq("itemid", item.getId());
                  if (favoriteitemDao.selectOne(queryWrapper) != null)
                        itemVO.setIsFavorite(1);
                  else
                        itemVO.setIsFavorite(0);
            }

            itemVO.setSales(countItemNum(itemVO.getId()));
            return itemVO;
      }

      private ItemAttrVO entityToVO(List<Itemattr> itemattrList) {
            ItemAttrVO itemAttrVO = new ItemAttrVO();
            Itemattr itemattr = itemattrList.get(0);
            itemAttrVO.setItemId(itemattr.getItemid());
            itemAttrVO.setAttrname(attributesDao.selectById(itemattr.getAttrid()).getAttrname());
            itemAttrVO.setPrice(itemDao.selectById(itemattr.getItemid()).getPrice());
            if (specialofferDao.selectById(itemattr.getItemid()) != null)
                  itemAttrVO.setSpecialrate(specialofferDao.selectById(itemattr.getItemid()).getRate());
            else
                  itemAttrVO.setSpecialrate(1);
            itemAttrVO.setStock(itemDao.selectById(itemattr.getItemid()).getStock());
            List<AttrVO> attrVOList = new ArrayList<>();
            for (Itemattr itemattr1 : itemattrList) {
                  attrVOList.add(entityToVO(itemattr1));
            }
            itemAttrVO.setAttrList(attrVOList);
            return itemAttrVO;
      }

      private AttrVO entityToVO(Itemattr itemattr) {
            AttrVO attrVO = new AttrVO();
            attrVO.setAttrvalue(attrvaluesDao.selectById(itemattr.getValueid()).getAttrvalue());
            attrVO.setRate(itemattr.getRate());
            attrVO.setSrc(pictureDao.selectById(itemattr.getPictureid()).getSrc());
            return attrVO;
      }

      private double getAvgStar(Item item) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("itemid", item.getId());
            List<Itemeval> itemevalList = itemevalDao.selectList(queryWrapper);
            double star = 0.0;
            double totalStar = 0.0;
            for (Itemeval itemeval : itemevalList) {
                  totalStar += itemeval.getStar();
            }
            if (itemevalList.size() > 0) {
                  star = new BigDecimal(totalStar / itemevalList.size()).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
            }
            return star;
      }

      private int countItemNum(int itemid) {
            QueryWrapper<OrderItem> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("itemid", itemid);

            List<OrderItem> orderItemList = orderItemDao.selectList(queryWrapper);
            int sum = 0;
            for (OrderItem orderItem : orderItemList) {
                  sum += orderItem.getNum();
            }
            return sum;
      }

}
